package se.djupfeldt.oscar.logbook.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class NmeaXmlParser {
    private Document dom;
    
    private String version = "3.01";
    
    public NmeaXmlParser(String version) {
	this.version = version;
    }
    
    public static void main(String[] args) {
	NmeaXmlParser xmlParser;
	if (args.length == 1)
	    xmlParser = new NmeaXmlParser(args[0]);
	else
	    xmlParser = new NmeaXmlParser("3.01");
	
	xmlParser.parseXmlFile();
	xmlParser.parseDocument();
    }

    private void parseXmlFile(){
	//get the factory
	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

	try {
	    DocumentBuilder db = dbf.newDocumentBuilder();
	    dom = db.parse("config/nmea-" + version + ".xml");

	}catch(ParserConfigurationException pce) {
	    pce.printStackTrace();
	}catch(SAXException se) {
	    se.printStackTrace();
	}catch(IOException ioe) {
	    ioe.printStackTrace();
	}
    }

    private void parseDocument() {
	StringBuilder sb = new StringBuilder();
	sb.append("package se.djupfeldt.oscar.logbook.utils;");
	sb.append("\n").append("public class NMEA" + version.replaceAll("\\.", "_") + " {");
	sb.append("\n");
	Element docEle = dom.getDocumentElement();

	NodeList nl = docEle.getElementsByTagName("sentence");
	if(nl != null && nl.getLength() > 0) {
	    for(int i = 0; i < nl.getLength(); i++) {
		Element sentenceElement = (Element) nl.item(i);
		String sentenceName = sentenceElement.getAttribute("name");
		sb.append("\t");
		sb.append("public static class " + sentenceName + "{");
		sb.append("\n");

		sb.append("\t\t");
		sb.append("public enum Fields {");
		
		NodeList fNodes = sentenceElement.getElementsByTagName("field");
		for (int j = 0; j < fNodes.getLength(); j++) {
		    Element fieldElement = (Element) fNodes.item(j);
		    String fieldName = fieldElement.getAttribute("name");
		    boolean optional = false;
		    String fieldOptional = fieldElement.getAttribute("optional");
		    if (fieldOptional == null || fieldOptional.equalsIgnoreCase("false") || fieldOptional.isEmpty()) {
			optional = false;
		    } else {
			optional = true;
		    }
		    
		    String fieldType = fieldElement.getAttribute("type");
		    if (fieldType == null || fieldType.isEmpty()) {
			fieldType = "standard";
		    }
		    sb.append("\n").append("\t\t\t");
		    sb.append(fieldName.replaceAll(" ", "").replaceAll("\\.", "_") + "(\"" + fieldName + "\", " + optional + ", \"" + fieldType + "\")");
		    sb.append(",");
		}
		sb.deleteCharAt(sb.lastIndexOf(",")).append(";");
		sb.append("\n\n").append("\t\t\t").append("public final String key;");
		sb.append("\n").append("\t\t\t").append("public final boolean optional;");
		sb.append("\n").append("\t\t\t").append("public final String fieldType;");

		sb.append("\n\n").append("\t\t\t");
		sb.append("private Fields(String key, boolean optional, String fieldType) {");
		sb.append("\n").append("\t\t\t\t").append("this.key = key;");
		sb.append("\n").append("\t\t\t\t").append("this.optional = optional;");
		sb.append("\n").append("\t\t\t\t").append("this.fieldType = fieldType;");
		sb.append("\n").append("\t\t\t").append("}");
		sb.append("\n").append("\t\t").append("}");
		sb.append("\n").append("\t").append("}");
	    	sb.append("\n");
	    }
	}
	
	sb.append("}");
	
	System.out.println(sb);
	File output = new File("NMEA" + version.replace("\\,", "_") + ".java");
	try {
	    PrintWriter pw = new PrintWriter(output);
	    pw.append(sb.toString());
	    pw.close();
	} catch (FileNotFoundException e) {
	    e.printStackTrace();
	}
    }
}
